﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;
using System.Threading.Tasks;

namespace KC.Library.Web.UI
{
	public static class ListBoxes
	{
		/// <summary>Moves all selected ListItems in a ListBox up by one</summary>
		/// <param name="lic">ListItemCollection from ListBox.Items</param>
		public static void MoveSelectedListItemsUp(ref ListBox lb)
		{
			int ContiguosityBreak = GetContiguosityBreakpoint(lb.Items, false);
			ListItemCollection lic2 = new ListItemCollection();

			// Build a list of ListItems and move the selected ones up by one
			for (int i = 0; i < lb.Items.Count; i++) {
				ListItem li = lb.Items[i];
				if (i > ContiguosityBreak && lic2.Count > 0 && li.Selected) lic2.Insert(lic2.Count - 1, li);
				else lic2.Add(li); }

			// Move these new listitems back into the listbox
			lb.Items.Clear();
			foreach (ListItem li in lic2) lb.Items.Add(li);
		}
		/// <summary>Moves all selected ListItems in a ListBox down by one</summary>
		/// <param name="lic">ListItemCollection from ListBox.Items</param>
		public static void MoveSelectedListItemsDown(ref ListBox lb)
		{
			int ContiguosityBreak = GetContiguosityBreakpoint(lb.Items, true);

			// Build a list of ListItems and move the selected ones down by one
			ListItemCollection lic2 = new ListItemCollection();
			foreach (ListItem li in lb.Items) if (!li.Selected) lic2.Add(li);

			for (int i = 0; i < lb.Items.Count; i++)
				if (lb.Items[i].Selected) {
					if (i >= ContiguosityBreak) lic2.Insert(i, lb.Items[i]);
					else if (i == 2) lic2.Insert(3, lb.Items[i]);
					else if (i == lb.Items.Count - 1) lic2.Insert(0, lb.Items[i]);
					else if (i < lic2.Count) lic2.Insert(i + 1, lb.Items[i]);
					else if (i == lic2.Count) lic2.Add(lb.Items[i]); }

			// Move these new ListItems back into the original ListBox
			lb.Items.Clear();
			foreach (ListItem li in lic2) lb.Items.Add(li);
		}
		/// <summary>Given a ListItemCollection, finds the index of the first one that isn't selected.
		/// The purpose of this is so we don't move the first one up to index -1 and if you have a bunch
		/// of selected ListItems at the top of a listbox, those don't move up.  But if you select items
		/// 0, 1, 2, and 4, then item 4 should move up to index 3.</summary>
		/// <param name="lic">ListItemCollection from ListBox.Items</param>
		/// <param name="CountBackwards">Count backwards?</param>
		/// <returns>Contiguosity Breakpoint - index of first unselected ListItem</returns>
		/// <remarks>GetContiguosityBreakpoint - i.e. the point at which we break the contiguousness of 
		/// a list of selected items</remarks>
		private static int GetContiguosityBreakpoint(ListItemCollection lic, bool CountBackwards)
		{
			if (CountBackwards) {
				for (int i = lic.Count - 1; i >= 0; i--)
					if (!lic[i].Selected) return i;
				return 0; }
			else {
				for (int i = 0; i < lic.Count; i++)
					if (!lic[i].Selected) return i;
				return lic.Count - 1; }
		}
	}
}

